{If the active window has an active editing field, }
{ it automatically processes most key }
{ strokes. In this example, we only check for }
{ the Tab key, which is used to tab to the next}
{ or previous field (Shift-Tab)… }
doKeyDown, doAutoKey: { }
if (Poll.Key.Chr = TabKey) and not (Poll.Modifiers.CmdKey or Poll.Modifiers.OptionKey or Poll.Modifiers.ControlKey) then
begin {If the Tab key was typed without the Command,}
{ Option or Control modifier keys, tab to the }
{ next / previous field. }
{ In a full-featured application, you would }
{ likely validate a field for errors before }
{ proceeding to the field clicked by the user. }
{ In this demo, no validation is done. }
SaveFieldString; {Save the field's edited text as the field's string }
Field := ActiveFieldNumber; {Determine the active field number }
if not Poll.Modifiers.ShiftKey then {TAB: to next field… }
Field := Field + 1 - 3 * ord(Field = 3) { Add 1. If field=3, start at 1 again. }
else {SHIFT-TAB: to previous field… }
Field := Field - 1 + 3 * ord(Field = 1); { Subtract 1. If field=1, start at 3. }
ActivateField(Field, teSelectAll); {Select all the text in the newly activated field }
end; { }
otherwise {All other events are ignored }
end { }
end;
{ A c t i o n i n D e m o W i n d o w 3 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine responds to actions made by the user in demo window 3. The actions include: }
{ • Clicking on an icon (Cursor Zone over the icon) }
{ • Clicking a radio button }
procedure ActionInWindow3;
var
ClickedZone: integer; {Cursor zone clicked by user }
Button: integer; {Button number counter }
begin
case Poll.What of {Determine what the user did (what event)… }
{ U s e r C l i c k e d I n T h e W i n d o w : - }
{The only click we care about in this window is if }
doClick: { it occurs in either of the two icons… }
begin { }
ResetMouseClicks; {Only 1st mouse-down is needed. Ignore rest. }
ClickedZone := FindCursorZone(Poll.Mouse.Down[1].Where); {Determine which cursor zone was clicked }
{ by the user. }
if (ClickedZone <> 0) and (ClickedZone <> MidiPort) then{If a Cursor Zone was clicked, and the clicked }
begin { zone is different from the currently selected }
{ MIDI port (ie: it was changed)… }
if ClickedZone = PrinterIcon then {Depending on which icon was clicked, set the }
MidiPort := PrinterIcon { MidiPort variable to the selected icon. }
else { }
MidiPort := ModemIcon; { }
DrawIcon(PrinterIcon, 20, 32, enabled, MidiPort = PrinterIcon); {Redraw the printer and modem }
DrawIcon(ModemIcon, 65, 32, enabled, MidiPort = ModemIcon); { icons as currently selected. }
end { }
end; { }
doButton: { U s e r C l i c k e d A B u t t o n : - - - }
begin { }
for Button := MidiHalfMeg to MidiTwoMeg do {Cycle through all 3 speed buttons and set only }
SelectButton(Button, Button = Poll.Button.Num); { the selected one. Turn the others off. }
MidiSpeed := Poll.Button.Num; {Keep track of the selected button }
end; { }
otherwise {Ignore all other events }
end { }
end;
{ A c t i o n i n D e m o W i n d o w 4 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine responds to actions made by the user in demo window 4. This routine is here for cosmetic reasons }
{ only, and you can get rid of it if you want. }
procedure ActionInWindow4;
begin
end;
{ A c t i o n i n D e m o W i n d o w 5 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine responds to actions made by the user in demo window 5. The only thing the user can do is click the }
{ default OK button, which closes the window. }
procedure ActionInWindow5;
begin
if Poll.What = doButton then {If the user clicked a button… }
CloseTheWindow(DemoWindow5); { end this demo by closing its window. }
end; { }
{ A c t i o n i n D e m o W i n d o w 6 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine responds to actions made by the user in demo window 6. Dynamic Alerts take care of responding to }
{ any action from the user, so you don't have to write any code for it. This routine is here for cosmetic reasons }
{ only, and you can get rid of it if you want. }
procedure ActionInWindow6;
begin
end;
{ A c t i o n i n D e m o W i n d o w 7 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine responds to actions made by the user in demo window 7. The only thing you can do is select an item }
{ in a pop-up menu. }
procedure ActionInWindow7;
const
SilentContinueAlert = -11500; {Button definition for a "Continue" dynamic alert }
{ that doesn't beep the user. }
var
AltButton: integer; {Button number clicked in an alert box }
begin
if Poll.What = doPopUpMenu then {The only thing you can do: use a pop-up menu }
case Poll.Menu.Num of {Determine which Pop-Up Menu was selected… }
popMenu1, popMenu5: {Pop-Up Menus 1 and 5 use a bullet (•) to mark a }
PopUpMark(Poll.Menu.Num, Poll.Menu.Item, DotChar); { selected item. Mark the new selection now. }
popMenu2, popMenu3: {Pop-Up Menus 2 and 3 use a check (√) to mark }
CheckPopUp(Poll.Menu.Num, Poll.Menu.Item, on); { selected items. Mark the new selection. }
popMenu4: {This menu is a "fixed title" pop-down menu. }
{ Such menus are usually used to "do some- }
{ thing now". This demo just displays an alert.}
AltButton := AlertBox(WatersEdgeLogo, 'Your application would do something now, such as displaying a dialog that lets the user specify formatting characteristics.', SilentContinueAlert);
end { }
end;
{ A c t i o n i n D e m o W i n d o w 8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ There are three routines for responding to events in this window. The first two are button value drawing routines }
{ that display a button's value. They are called when the button is clicked, or when the window is refreshed. }
{ This routine displays a value in the tool bar. It is called whenever the 'plus' or 'minus' buttons are used, and }
{ when the screen is refreshed. }
procedure ActionInWindow8_DrawToolBarValue;
var
theNumber: str255; {Button's value represented as a string }
begin
NumToString(ToolBarValue, theNumber); {Convert tool bar number to a string }
TextFont(systemFont); {Set the window's font to Chicago 12pt. }
TextSize(12); { }
PenColorNormal; {PEN: 1 x 1 size, black color, patCopy mode }
TextInBox(theNumber, 401, 6, 439, 22, teJustCenter, true); {Draw the value in the window's tool bar with a }
end; { frame around it. }
{ This routine displays the value of the 'Globe' button. It is called whenever the 'Globe' button is used, and when }
{ the screen is refreshed. }
procedure ActionInWindow8_DrawGlobeValue;
var
ButtonValue: integer; {Globe button's value }
theNumber: str255; {Button's value represented as a string }
begin
ButtonValue := GetPictButtonVal(GlobeButton); {Get the 'globe' button's value }
NumToString(ButtonValue, theNumber); {Convert to a string }
theNumber := concat(theNumber, '°'); {Add the degree symbol to the end of the string }
TextFont(systemFont); {Set the window's font to Chicago 12pt. }
TextSize(12); { }
TextInBox(theNumber, 408, 201, 448, 217, teJustRight, false); {Draw the button's value below the button }
end; { }
{ This routine responds to actions made by the user in demo window 8. This window contains mostly Picture }
{ Buttons, so the response is limited to the user clicking on these buttons. Notice that the buttons are organized }
{ into different types: simple binary clusters, multi-stage buttons, radio button clusters, etc. }
procedure ActionInWindow8;
var
theButton: integer; {Button counter }
begin
case Poll.What of {Determine what the user did (what event)… }
doPopUpMenu: { P o p - U p M e n u W a s S e l e c t e d : }
begin { }
PopUpMark(Poll.Menu.Num, Poll.Menu.Item, '√'); {Check selected item (others are unchecked) }
if Poll.Menu.Num = ButtonSpeedMenu then {If this menu regulate's the 'globe' button speed,}
SetPictButtonAccel(GlobeButton, Poll.Menu.Item - 1); { set the button's acceleration curve. }
end; { }
doPictButton: { P i c t u r e B u t t o n W a s S e l e c t e d : }
case Poll.Button.Num of {This section demonstrates typical interaction }
{ with check boxes, radio button groups and }
{ push buttons. }
LeftAlignButton, CenterAlignButton, RightAlignButton, JustifyButton: {Cycle through the group and turn }
for theButton := LeftAlignButton to JustifyButton do { off the ones that weren't clicked}
SetRect(Rectangle, left, top, right, bottom); {Convert the specified co-ordinates into a rect. }
FrameRect(Rectangle); {Draw the group's box }
if Str <> '' then {If a string was included as the group's title, it }
begin { will be centered at the top… }
Width := StringWidth(Str); {Calculate the text's width in pixels }
TextRect.left := (Rectangle.left + Rectangle.right) div 2 - (Width div 2) - 2; {Calculate a rectangle so that it }
TextRect.right := TextRect.left + Width + 4; { fits on the top edge of the group's box. It's }
TextRect.top := Rectangle.top - 8; { wide enough for the title, plus a 2 pixel }
TextRect.bottom := TextRect.top + 16; { border on each side. }
TextBox(ptr(ord(@Str) + 1), length(Str), TextRect, teJustCenter); {Draw the group's title }
end { }
end; { }
{ D r a w C o n t e n t s o f D e m o W i n d o w 1 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine draws all the text and lines in demo window 1. It is called when first creating the window and when }
{ the window needs to be refreshed. Note that objects that are created by Tools Plus are refreshed automatically. }
procedure DrawWindow1Contents;
begin
{ C o m m e n t s - - - - - - - - }
PenPat(Gray); {Use gray pattern for drawing framing boxes }
TextFont(Geneva); {Draw all comments using Geneva 9pt, plain }
TextSize(9); { style. }
TextFace([]); { }
{Comments for left list box… }
TextInBox('This left text list uses the standard system font, just like normal list boxes.', 38, 108, 236, 140, teJustLeft, false);
{Comments for right list box… }
TextInBox('This one uses Geneva 9pt. Each list box can have its own font.', 295, 108, 416, 150, teJustLeft, false);
{Comments for Cursor Zones… }
TextInBox('This is a "Plus Cursor" zone. The cursor changes when entering this area.', 275, 150, 400, 189, teJustCenter, true);
TextInBox('This is a "Cross Cursor" zone. The cursor changes when entering this area.', 275, 193, 400, 232, teJustCenter, true);
{Comments for mini-buttons… }
TextInBox('These buttons are drawn in bold Geneva 9pt. Many different fonts, sizes and styles can be used.', 120, 140, 240, 190, teJustLeft, false);
PenSize(3, 3); {Make the pen 3x3 pixels for a fatter line }
GroupBox('', 14, 137, 242, 192); {Draw a gray, fat box around the mini buttons }
{Comment at bottom of the window… }
TextInBox('Double-click a radio button or a line in a list box to mean “select this and click ‘OK’.” (Note that the OK button flashes.) This OPTION is easily implemented.', 5, 290, 420, 320, teJustCenter, false);
{ L i s t B o x T i t l e s - - - - - - }
TextFont(systemFont); {Set the window's font to Chicago 12pt. }
TextSize(12); { }
MoveTo(5, 19); {Draw the word 'Left' at local co-ordinates 5,19 }
DrawString('Left:'); { for the left list box. }
MoveTo(253, 19); {Draw the word 'Right' at local co-ord 253,19 }
DrawString('Right:'); { for the right list box. }
{ R a d i o B u t t o n G r o u p ' s T i t l e - }
PenNormal; {Reset pen pattern to black, and pen size to 1x1}
GroupBox('Choose', 165, 212, 231, 273); {Draw a box around the radio button group and }
end; { give the group a title. }
{ D r a w C o n t e n t s o f D e m o W i n d o w 2 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine draws all the text and lines in demo window 2. It is called when first creating the window and when }
{ the window needs to be refreshed. Note that objects that are created by Tools Plus are refreshed automatically. }
procedure DrawWindow2Contents;
var
Rectangle: rect; {Rectangle for drawing comments (text) }
begin
{ C o m m e n t a b o v e f i e l d s - - - }
TextFont(Geneva); {Draw all comments using Geneva 9pt. }
TextSize(9); { }
PenPat(Gray); {Any line drawing will be done with a gray pattern}
TextInBox(concat('Click the "zoom box" to zoom between the standard and user co-ordinates.', ReturnKey, ReturnKey, 'The scroll bars don''t actually scroll anything in this demo. But notice that they are automatically repositioned when you resize the window.'), 10, 2, 191, 95, teJustLeft, false);
{ C o m m e n t f o r f i r s t f i e l d - - - }
TextInBox('The first field is "length limited." It accepts a maximum of 30 characters, (the length of the field), and does not scroll or require word-wrap.', 220, 15, 375, 77, teJustLeft, false);
SetRect(Rectangle, 215, 10, 380, 82); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(215, 46); {Draw a gray line from the first field to the box }
LineTo(195, 105); { that was previously completed. }
{ C o m m e n t f o r s e c o n d f i e l d - - }
TextInBox('The second field is a "single-line" editing field. It scrolls to keep the selection in view, and does not require word wrap.', 220, 97, 375, 146, teJustLeft, false);
SetRect(Rectangle, 215, 92, 380, 151); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(215, 126); {Draw a gray line from the second field to the }
LineTo(195, 126); { box that was previously completed. }
{ C o m m e n t f o r t h i r d f i e l d - - - }
TextInBox('The third field is a "multiple-line" editing field. It scrolls to keep the selection in view, and uses word wrap to break long words.', 220, 166, 375, 215, teJustLeft, false);
SetRect(Rectangle, 215, 161, 380, 220); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(215, 207); {Draw a gray line from the third field to the box }
LineTo(195, 148); { that was previously completed. }
{ C o m m e n t s a t b o t t o m - - - - }
TextInBox('Try editing the text in the fields (above). The Edit menu automatically works with the active field (check out the Undo!)', 10, 220, 200, 260, teJustLeft, false);
TextInBox('Notice that each editing field can have its own font!', 220, 235, 375, 260, teJustLeft, false);
end;
{ D r a w C o n t e n t s o f D e m o W i n d o w 3 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine draws all the text and lines in demo window 3. It is called when first creating the window and when }
{ the window needs to be refreshed. Note that objects that are created by Tools Plus are refreshed automatically. }
procedure DrawWindow3Contents;
begin
TextFont(Geneva); {Comment at top of window (drawn in Geneva }
TextSize(9); { 9pt)… }
TextInBox('This demo simulates MIDI Interface settings. Click on an icon to select it.', 10, 100, 230, 200, teJustCenter, false);
DrawIcon(PrinterIcon, 20, 32, enabled, MidiPort = PrinterIcon); {Redraw the printer and modem icons as }
DrawIcon(ModemIcon, 65, 32, enabled, MidiPort = ModemIcon);{ currently selected. }
TextFont(systemFont); {Box and title around icon group and radio }
TextSize(12); { button group (drawin in Chicago 12 pt.)… }
GroupBox('Port', 7, 17, 111, 80); {Draw a box around the Printer and Modem }
{ icons, and give the group a title. }
GroupBox('Speed', 128, 17, 231, 80); {Draw a box around the interface Speed radio }
end; { buttons, and give the group a title. }
{ D r a w C o n t e n t s o f D e m o W i n d o w 4 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine draws all the text in demo window 4. It is called when first creating the window and when the window }
{ needs to be refreshed. }
procedure DrawWindow4Contents;
begin
MoveTo(10, 21); {This window has been previously set to draw }
DrawString('A lengthy process is being simulated.'); { characters using Chicago 12 pt. Simply }
MoveTo(10, 85); { display the message. }
DrawString(concat('Type ', chr(CommandMark), '-. to cancel the simulation.')); { }
end; { }
{ D r a w C o n t e n t s o f D e m o W i n d o w 5 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine draws all the text and pictures in demo window 5. It is called when first creating the window and }
{ when the window needs to be refreshed. This routine has the following unique routines: }
{ • Color-independent drawing (doesn't care about the monitor's settings) }
{ • Color-dependent drawing (different drawing dependent on number of colors, grays, or if black & white) }
{ • Multiple-monitor compatibility (each monitor can have different settings) }
{ The color PICTure looks good only in 256 colors, but it also looks good in 256 shades of gray as well as 16 }
{ shades of gray (8 bit and 4 bit gray). So this demo decides which PICTure to draw depending on the monitor's }
{ settings. }
{ NOTE: Tools Plus may not recognize if you change your monitor settings while running your application in }
{ the development environment. It will recognize the change when your application is compiled to be a stand- }
{ alone (double-clickable) application. }
procedure DrawWindow5Contents;
var
TheScreen: integer; {Screen counter for multiple-screen drawing }
hPicture: PicHandle; {Handle to a PICTure resource }
viewRect: rect; {Viewing rectangle for the picture }
begin
{ C o l o r I n d e p e n d e n t D r a w i n g : - }
{Drawing that doesn't care about the monitor's }
{ setting can be done before or after the }
{ color-dependent drawing. }
TextInBox(concat('This window demonstrates color-dependent, color-independent, and multiple-screen drawing. Use the Monitors desk accessory to change the monitor’s settings.', ReturnKey, ' If you have two monitors, drag the window across so that half is on each screen.'), 10, 5, 300, 70, teJustLeft, false);
{ C o l o r D e p e n d e n t D r a w i n g : - }
{The following code is for drawing that depends }
{ on the number of available colors, shades }
{ of gray, or if the monitor is set to Black & }
{ White. It also makes the routine multiple- }
{ monitor compatible. }
for TheScreen := 1 to NumberOfScreens do {Repeat drawing once for each logical screen }
begin { (monitor with different settings)… }
BeginUpdateScreen(TheScreen); {Begin the update for this logical screen. All }
{ drawing is limited (clipped) to the one logical }
{ screen. }
if ((ScreenDepth >= 8) or ((ScreenDepth = 4) and (not ScreenHasColors))) then {Use the color pictures }
hPicture := GetPicture(ColorPICT) { only if 256 colors or 16 shades of gray are }
else { available (or better). Otherwise, use the }
hPicture := GetPicture(BlackAndWhitePICT); { Black & White equivalent. }
viewRect := hPicture^^.picFrame; {Determine the picture's framing rectangle }
{The picture's rectangle is in the local window }
{ co-ordinates of the application that created }
{ it, so convert it to the local co-ordinates of }
OffsetRect(viewRect, -viewRect.left, -viewRect.top); { this demo window. }
{Offset the picture's rectangle such that it is }
OffsetRect(viewRect, 30, 90); { drawn below the descriptive text. }
DrawPicture(hPicture, viewRect); {Draw the picture in its destination rectangle. }
ReleaseResource(handle(hPicture)); {Release the resource to conserve memory }
EndUpdateScreen; {End the update to the current logical screen }
end { }
end; { }
{ D r a w C o n t e n t s o f D e m o W i n d o w 6 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ Dynamic Alerts take care of all drawing, so you don't have to write any code for it. This routine is here for }
{ cosmetic reasons only, and you can get rid of it if you want. }
procedure DrawWindow6Contents;
begin
end;
{ D r a w C o n t e n t s o f D e m o W i n d o w 7 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine draws all the text and lines in demo window 7. It is called when first creating the window and when }
{ the window needs to be refreshed. }
procedure DrawWindow7Contents;
var
Rectangle: rect; {Rectangle for drawing comments (text) }
begin
{ C o m m e n t s b e s i d e P o p - U p M e n u s}
{All comments use Geneva 9pt, as set when }
{ this window was first opened. }
PenPat(Gray); {Any line drawing will be done with a gray pattern}
{ C o m m e n t f o r f i r s t m e n u - - - }
TextInBox('This is a standard Pop-Up Menu. Nothing special here, except that it’s really easy to do.', 235, 15, 380, 51, teJustLeft, false);
SetRect(Rectangle, 230, 12, 385, 55); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(215, 26); {Draw a gray line from the first menu to the box }
LineTo(230, 26); { completed above. }
{ C o m m e n t f o r s e c o n d m e n u - - }
TextInBox('This Pop-Up Menu has icons. But unlike System-7’s pop-ups, the selected item’s icon can appear in the pop-up box.', 235, 65, 380, 113, teJustLeft, false);
SetRect(Rectangle, 230, 62, 385, 117); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(220, 76); {Draw a gray line from the second menu to the }
LineTo(230, 76); { box completed above. }
{ C o m m e n t f o r t h i r d m e n u - - - }
TextInBox('This Pop-Up Menu contains icons without any text. It looks like a custom menu but it’s not.', 235, 125, 380, 161, teJustLeft, false);
SetRect(Rectangle, 230, 122, 385, 165); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(175, 136); {Draw a gray line from the third menu to the box }
LineTo(230, 136); { completed above. }
{ C o m m e n t f o r f o u r t h m e n u - - }
TextInBox('This is a “Pop-Down” menu. It’s like an on-screen pull-down menu, and is usually used to “do something now.”', 235, 185, 380, 233, teJustLeft, false);
SetRect(Rectangle, 230, 182, 385, 237); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(220, 196); {Draw a gray line from the fourth menu to the }
LineTo(230, 196); { box completed above. }
{ C o m m e n t f o r f i f t h m e n u - - - }
TextInBox('Pop-Up Menus can use any font and size, and can be auto-sized for a perfect look.', 235, 245, 380, 281, teJustLeft, false);
SetRect(Rectangle, 230, 242, 385, 285); {Define the outline around the comment }
FrameRect(Rectangle); {Draw a gray box around the comment }
MoveTo(150, 246); {Draw a gray line from the fifth menu to the box }
LineTo(230, 246); { box completed above. }
end; { }
{ D r a w C o n t e n t s o f D e m o W i n d o w 8 : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine draws all the text and lines in demo window 8. Tools Plus takes care of all the button drawing. The }
{ band at the top of this window demonstrates how to make a tool bar in a window. }
procedure DrawWindow8Contents;
var
TheScreen: integer; {Screen counter for multiple-screen drawing }
ToolBarRect: rect; {Rectangle for drawing toolbar }
begin
{ D r a w T o o l B a r B a c k g r o u n d }
SetRect(ToolBarRect, -1, -1, 473, 29); {Define the toolbar's rectangle }
{Draw the toolbar gray if the monitor is set to }
{ 4-bits or better… }
for TheScreen := 1 to NumberOfScreens do {Repeat drawing once for each logical screen }
begin { (monitor with different settings)… }
PenColorNormal; {PEN: 1 x 1 size, black color, patCopy mode }
BeginUpdateScreen(TheScreen); {Begin the update for this logical screen. All }
{ drawing is limited (clipped) to the one logical }
{ screen. }
if ScreenDepth >= 4 then {If this logical screen is set to a depth of 4-bits }
begin { or more (16 colors/grays)… }
RGBForeColor(ToolBarGray); { }
PaintRect(ToolBarRect); {Paint the toolbar the medium dark gray }
end; { }
EndUpdateScreen; {End the update to the current logical screen }
end; { }
PenColorNormal; {PEN: 1 x 1 size, black color, patCopy mode }
FrameRect(ToolBarRect); {Draw a black 1-pixel frame around the toolbar }
{ B u t t o n ' s V a l u e s }
ActionInWindow8_DrawToolBarValue; {Draw the value in the window's tool bar }
ActionInWindow8_DrawGlobeValue; {Draw the globe button's value }
TextFont(Geneva); {All comments are drawn using Geneva font }
TextSize(12); {One comment is drawin in Geneva 9pt… }
MoveTo(6, 134); { }
DrawString('Picture Buttons are very versatile. You define their look and behavior.'); { }
PenPat(Gray); {Any line drawing will be done with a gray pattern}
MoveTo(0, 118); {Draw gray line dividing upper and lower part of }
LineTo(472, 118); { the window. }
TextSize(9); {All other comments use Geneva 9pt. }
{ C o m m e n t f o r A r r o w B u t t o n s - }
TextInBox('These buttons use an icon for each stage, giving you absolute control over their appearance.', 10, 41, 155, 80, teJustLeft, false);
MoveTo(120, 29); {Draw a gray line from this comment to the }
LineTo(120, 40); { buttons it refers to. }
{ C o m m e n t f o r A l i g n m e n t B u t t o n s }
TextInBox('These “SICN 3D” buttons are available in two sizes. They use a single icon each. Tools Plus does all the 3D drawing. Activate another window and see how they look disabled.', 167, 41, 358, 110, teJustLeft, false);
MoveTo(218, 29); {Draw a gray line from this comment to the }
LineTo(218, 40); { buttons it refers to. }
MoveTo(322, 29); { }
LineTo(322, 40); { }
{ C o m m e n t f o r U t i l i t y B u t t o n s - }
TextInBox('This pair of buttons behaves as one control. Continuous events are generated while the mouse button is held down.', 368, 41, 471, 118, teJustLeft, false);
MoveTo(450, 29); {Draw a gray line from this comment to the }
LineTo(450, 40); { buttons it refers to. }
{ C o m m e n t f o r P l a i n I c o n B u t t o n s }
{ C o m m e n t f o r S c r o l l i n g B u t t o n }
TextInBox('These buttons have “values” associated with them. You can raise/lower the value by clicking on opposite sides of the button. The left button uses only 1 icon!', 204, 154, 398, 203, teJustLeft, false);
MoveTo(147, 158); { }
DrawString('Step'); { }
MoveTo(172, 158); { }
DrawString('Scroll'); { }
{ C o m m e n t f o r D u a l - S t a g e B u t t o n }
TextFont(Geneva); {All text is drawn in Geneva 9pt. }
TextSize(9); { }
DrawWindow5Contents; {Draw the rest of the objects in this demo }
{ window. All Tools Plus objects are auto- }
{ matically updated when a window needs to }
{ be refreshed, such as when you bring it to }
{ the front to make it active. }
{ Non-Tools Plus objects (ie: those you }
{ create) have to be redrawn separately in }
{ response to a doRefresh event, so it's a }
{ good idea to keep them in a separate }
{ routine. }
EnableMenu(FileMenu, CloseItem, enabled); {Enable the File menu's Close command, now }
end; { that there's a window to close. }
{ C r e a t e D e m o W i n d o w 6 : - - - - - - - - - - - - - - - - - - - - }
{ This demo shows off Tools Plus's Dynamic Alerts. Dynamic Alerts are self contained (you don't have to do }
{ anything other than call it and wait for the user to respond). Breaking from tradition that was previously }
{ established by the 'OpenDemoWindow…' routines, this demo does everything pertaining to displaying }
{ Dynamic Alerts, detecting user action, and responding to events. }
procedure OpenDemoWindow6;
const
ContinueAlert = 11500; {Button definition for a "Continue" dynamic alert }
SilentContinueAlert = -11500; {Button definition for a "Continue" dynamic alert }
{ that doesn't beep the user. }
EndAlert = -33987; {Button definition using three custom buttons }
var
AltButton: integer; {Alert button clicked by the user }
begin
{These first 2 alerts ignore which button that }
{ was clicked… }
AltButton := AlertBox(noteIcon, concat('This is an dynamic alert box. Dynamic Alerts automatically adjust to accommodate the text your application provides them. In fact, they’re smart enough to recognize “carriage returns” as “new line” commands.', ReturnKey, ReturnKey, 'Click “Continue” for more examples.'), ContinueAlert);
AltButton := AlertBox(stopIcon, concat('Icons…', ReturnKey, ReturnKey, 'You can display any icon you want in a Dynamic alert, including color icons.', ReturnKey, ReturnKey, 'AlertBox calls Tools Plus’s DrawIcon routine, so it’s smart enough to pick the right icon for your monitor’s settings.'), SilentContinueAlert);
{This alert displays 2 buttons: Yes and No. If }
{ the user answers Yes, the demo continues…}
if YesAltBut = AlertBox(noteIcon, 'Do you want to continue with more examples of Dynamic Alerts?', YesNoAlert) then
begin { }
AltButton := AlertBox(cautionIcon, 'Dynamic Alerts can even do unusual things, like alerts with no buttons (click in this window to get rid of it).', NoButtonAlert);
theIcon := theIcon + 1; {Increment the icon for the next picture button }
end { }
end; { }
{ R e s p o n s e s t o E v e n t s : = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = }
{ The following routines are invoked in response to events that were detected in the main event loop. }
{ U s e r C l i c k e d I n a c t i v e W i n d o w : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine is called in response to a "doChgWindow" event. Note that clicking between the active window }
{ and a desk accessory, or between two desk accessories does not generate a doChgWindow event. }
{ A doChgWindow event is generated only when the user tries to activate an inactive window belonging to }
{ your application. In a full featured application, you may want to validate the active editing field and perform any }
{ other verifications before activating the window. }
procedure ChangeWindow;
begin
ActivateWindow(Poll.Window); {Activate the requested window }
end;
{ C h o o s e A M e n u : - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - }
{ This routine is called in response to a "doMenu" event. A doMenu event indicates that the user selected a menu }
{ or typed a Command-key equivalent for a menu. Note that a doMenu event is not generated if a desk }
{ accessory's menu is selected. The Edit menu's Undo, Cut, Copy, Paste, and Clear items automatically interact }
{ with the active editing field without you having to do anything. }
procedure MenuSelection;
var
theButton: integer; {Button that was clicked in a Dynamic Alert }
begin
case Poll.Menu.Num of
ApplMenu: { A p p l e M e n u : - - - - - - - }
{The only item in the Apple menu that generates }
{ an event is the "About…" item. All we do is }
{ display a Dynamic Alert box… }
theButton := AlertBox(NoIcon, concat('T o o l s P l u s D e m o A p p l i c a t i o n', ReturnKey, ReturnKey, 'Water’s Edge Software', ReturnKey, 'PO Box 70022', ReturnKey, '2441 Lakeshore Road West', ReturnKey, 'Oakville, Ontario', ReturnKey, 'Canada, L6L 6M9', ReturnKey, ReturnKey, '(416) 219-5628', ReturnKey, ReturnKey, '(Click this window to continue)'), NoButtonAlert);
FileMenu: { F i l e M e n u : - - - - - - - }
case Poll.Menu.Item of {Determine the item selected within this menu… }
CloseItem: { Close… }
if FirstStdWindowNumber <> 0 then {If a standard window is open… }
CloseTheWindow(FirstStdWindowNumber) { close the front most standard window. }
else if FirstPaletteNumber <> 0 then {If a flating palette is open… }
CloseTheWindow(FirstPaletteNumber); { close the front most palette. }
QuitItem: { Quit… }
ExitTheDemo := true; { set the 'exit the demo' flag to true to indicate}
end; { we're ready to return to the Finder. }
DemosMenu: { D e m o s M e n u : - - - - - - }
begin {When selecting an item from the Demos menu, }
{ it means 'activate this demo window' if the }
{ window is already open, and 'open this demo}
{ window' if it isn't open. }
if Poll.Menu.Item = ToolBarItem then {If user selected the Hide/Show Tool Bar item… }
OpenDemoWindow9 { Open or closes (hide) the Tool Bar }
else { }
begin { }
ActivateWindow(Poll.Menu.Item); {Try to activate the window number that }
{ corresponds to the menu's item number. }
{ This will bring the window to the front. }
if not WindowIsOpen(Poll.Menu.Item) then {If the specified window is not open, it indicates }
{ the requested demo window is not open yet. }
{ So open the requested demo… }
case Poll.Menu.Item of {Determine the item selected within this menu }
1: { and open the specified demo window. }
OpenDemoWindow1; { }
2: { }
OpenDemoWindow2; { }
3: { }
OpenDemoWindow3; { }
4: { }
OpenDemoWindow4; { }
5: { }
OpenDemoWindow5; { }
6: { }
OpenDemoWindow6; { }
7: { }
OpenDemoWindow7; { }
8: { }
OpenDemoWindow8; { }
end { }
end { }
end; { }
PaletteDemoMenu: { P a l e t t e D e m o s M e n u : - - - - }
begin {The 'Palettes' menu is hierarchic, so you treat }
{ it like a separate pull-down menu. When }
{ selecting an item from the Palettes Demos }
{ menu, it means 'activate this palette window'}
{ if the window is already open, and 'open this }
{ palette window' if it isn't open. }
ActivateWindow(Poll.Menu.Item + VerticalPalette - 1); {Try to activate the palette number that }
{ corresponds to the menu's item number. }
{ This will bring the palette to the front. }
if not WindowIsOpen(Poll.Menu.Item + VerticalPalette - 1) then {If the specified palette is not open then }
{ display the palette… }
case Poll.Menu.Item of {Determine the item selected within this menu }
1: { and open the specified palette window. }
OpenDemoWindow10; { }
2: { }
OpenDemoWindow11; { }
end { }
end { }
end;
if not ExitTheDemo then {If the user has not quit the application… }
MenuHilite(0); { turn off the highlighted menu in the menu }
{ bar. This shows the user that the }
{ application has responded to the menu }
end; { selection. }
{ P r e p a r a t i o n s : = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = }
{ This routine does all the "set up" work for the demo, such as creating the menus and introducing the demo. }
{ In a full-featured application, you would probably open documents that were double-clicked from the Finder. }
procedure PrepareTheDemo;
const
QuitAlert = 11700; {Button definition for a 'Quit' Dynamic Alert }
SilentContinueAlert = -11500; {Button definition for a "Continue" dynamic alert }
{ that doesn't beep the user. }
var
AltButton: integer; {Button number clicked in an alert box }
begin
SetNullTime(1, maxNullTime); {Be a good neighbor to other applications by }
{ using fewer CPU cycles. }
CursorShape(watchCursor); {Change the cursor to a wrist watch }
MidiPort := ModemIcon; {By default, select the modem port for a MIDI }
AttachMenu(DemosMenu, 11, PaletteDemoMenu); {Attach the hierarchic 'palettes' menu to the }
{ 11th item in the 'Demos' pull-down menu. }
UpdateMenuBar; {Draw the menu bar with all its menu names }
{ E d i t i n g F i e l d s : - - - - - - }
hField1 := Str30Handle(NewStrHandle(30)); {Allocate memory for the editing fields' strings. }
hField2 := NewStrHandle(255); { Tools Plus fields reference their related }
hField3 := NewStrHandle(255); { string by this handle. }
{Display an alert that tells the user how to use }
{ the demo… }
AltButton := AlertBox(WatersEdgeLogo, concat('Welcome to the Tools Plus demo.', ReturnKey, ReturnKey, 'Use the “Demos” menu to explore each of the demos prepared for you. Feel free to play around with the various objects.', ReturnKey, ReturnKey, 'Click “Continue” to start the first demo.'), SilentContinueAlert);
OpenDemoWindow1; {Open the first demo window }
ResetCursor; {Get rid of the wrist watch cursor by resetting it }
{ to its proper shape (Tools Plus figures out }
{ its proper shape depending on where it is on }
end; { the screen). }
{ M a i n P r o g r a m : = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = }
{ The main program demonstrates the detection of, and response to events. Tools Plus events are more usable }
{ than those obtained from The Event Manager. }
begin
if not InitToolsPlus(0, 12, UseColor) then {Initialize Tools Plus with 0 extra handle blocks }
ExitToShell; { and a maximum of 11 open windows. Use }
{ Color QuickDraw if it’s available. If }
{ initialization fails, return to the Finder. }
PrepareTheDemo; {Prepare the demo by creating the menus and }
{ opening a sample window. }
ExitTheDemo := false; {The demo is not over yet }
while not ExitTheDemo do {Keep polling for an event until the Quit item is }
{ selected in the File menu… }
if PollSystem(Poll) then {If an event has been detected… }
case Poll.What of {Determine what kind of event has occurred… }
doMenu: {User selected a menu item… }
MenuSelection; { execute that menu item. }
doChgWindow: {User clicked on an inactive window… }
ChangeWindow; { activate the window the user clicked. }
doRefresh: {A window needs to be refreshed… }
RefreshWindow; { redraw the specified window. }
doGoAway: {User clicked a window's 'close box'… }
CloseTheWindow(Poll.Window); { close the affected window. }
{The user has clicked a button, typed a key, }
{ clicked in an inactive field, used a scroll }
{ bar, clicked a line in a list box, used a Pop- }